#include "AsyncComm.h"
#include "Session.h"
#include "communication/DataPacket.h"
#include "communication/socket/AsyncSocket.h"
#include "communication/serial/AsyncSerial.h"

Session::Session():m_lastPong(0)
{
	InitPacketHandlerTable();
}

Session::~Session()
{
}

bool Session::IsConnectionOk()
{
	//return m_socket.IsConnected();
	return true;
}

void Session::QueuePacket(DataPacket* packet)
{
	m_msgQueue.push(packet);
}

bool Session::FiniSession()
{
	//m_socket.Disconnect();
	m_userName.clear();
	m_passHash.clear();
	m_address.clear();
	return true;
}

void Session::InitClientSession()
{
//	m_socket.InitSocket(INVALID_SOCKET, this);

	char address[64];
	strcpy(address, m_address.c_str());
	char * pszPort = strchr(address, ':');
	if (pszPort != NULL)
	{
		pszPort[0] = 0;
		m_nPort = atoi(pszPort+1);
	}
	//m_socket.Connect(address, m_nPort);
}

bool Session::InitSession(const char* pszAddress, const char* pszUserName, const char* pszPassHash,AsyncCommType type )
{
	m_userName = pszUserName;
	m_passHash = pszPassHash;
	m_address  = pszAddress;
	InitClientSession();

	switch( type )
	{
	case eSerial:
		m_pComm = new AsyncSerial;
		break;
	case eTCP:
		m_pComm = new AsyncSocket;
		break;
	default:
		_LOG("Invalid Type");
		return false;
	}
	m_pComm->InitFD( INVALID_FD, this);
	return m_pComm->Connect(pszAddress);
}


bool Session::UpdateClientSession( int32 deltaTime )
{
	if( !m_pComm)
		return false;

	m_pComm->Update(deltaTime);
	if ( m_msgQueue.empty() )
		return false;

	DataPacket *packet;
	while ( !m_msgQueue.empty() )
	{
		packet = m_msgQueue.front();
		CR_ASSERT(packet);
		if ( packet )
		{
			this->HandlePacket(packet);
		}
		m_msgQueue.pop();
		PACKET_DELETE packet;
	}

	return true;
}


bool Session::Update(int32 deltaTime)
{

	return UpdateClientSession(deltaTime);
}

void Session::OnConnect(int32 errorCode)
{
}

void Session::OnDisconnect(int32 errorCode)
{
}

void Session::InitPacketHandlerTable()
{

}

void Session::SendPacket(DataPacket& packet)
{
	if(m_pComm && m_pComm->IsConnected() )
			m_pComm->SendPacket( &packet);
}

void Session::OutPacket(uint16 opcode)
{
	if(m_pComm && m_pComm->IsConnected() )
		m_pComm->OutPacket(opcode, 0, NULL);

	/*if(m_socket.IsConnected())
		m_socket.OutPacket(opcode, 0, NULL);*/
}
void Session::OutPacket(uint16 opcode, uint16 len, const void* data)
{
	if(m_pComm && m_pComm->IsConnected() )
		m_pComm->OutPacket(opcode, len, data);
}

bool Session::SendBData(const uint8* pData, uint8 nLen)
{
	m_pComm->BurstBegin();
	m_pComm->BurstSend( pData,nLen );
	m_pComm->BurstPush();
	m_pComm->BurstEnd();
	return true;
}